package com.taotao.tools.jackson.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;


/**
 * @Desc XML与Java实体类转换工具
 * @Author youbeiwuhuan
 * @Date 2021/12/30 11:09
 */
@Slf4j
public class XmlMapperUtils {

    public static final XmlMapper xmlMapper;

    static {
        xmlMapper = new XmlMapper();
        SimpleModule module = new SimpleModule();

        xmlMapper.registerModule(module);

//        JavaTimeModule javaTimeModule = new JavaTimeModule();
//        javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//        javaTimeModule.addSerializer(LocalDate.class,new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
//        javaTimeModule.addSerializer(LocalTime.class,new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
//
//        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
//        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
//
//        xmlMapper.registerModule(javaTimeModule);

        xmlMapper.setDefaultUseWrapper(false);

        // 字段为null，自动忽略，不再序列化
        xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        // XML标签名:使用骆驼命名的属性名，
        xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);

        xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);

        // 设置转换模式
        xmlMapper.enable(MapperFeature.USE_STD_BEAN_NAMING);

        // 缩进
        xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
    }

    /**
     * @param object
     * @return
     * @Description 将java对象转化为xml字符串
     * @Title beanToXml
     */
    public static String beanToXml(Object object) {
        try {
            return xmlMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            log.error(e.getMessage());
            throw new RuntimeException("Java对象转换为Xml失败", e);
        }
    }

    /**
     * @param xml
     * @param clazz
     * @return
     * @Description 将xml字符串转化为java对象
     * @Title xmlToBean
     */
    public static <T> T xmlToBean(String xml, Class<T> clazz) {
        try {
            return xmlMapper.readValue(xml, clazz);
        } catch (IOException e) {
            log.error(e.getMessage());
            throw new RuntimeException("Xml转换为Java对象失败", e);
        }
    }


    /**
     * @param xml
     * @param parametrized
     * @param parameterClasses
     * @param <T>
     * @Description 将xml字符串转化为java对象
     */
    public static <T> T xmlToBean(String xml, Class<T> parametrized, Class<?>... parameterClasses) {
        JavaType javaType = xmlMapper.getTypeFactory()
                .constructParametricType(parametrized, parameterClasses);
        try {
            return xmlMapper.readValue(xml, javaType);
        } catch (IOException e) {
            log.error(e.getMessage());
            throw new RuntimeException("Xml转换为Java对象失败", e);
        }
    }


    public static void main(String[] args) {
//        Person p= new Person("mike",44, LocalDateTime.now(),"football");
//
//        String s = beanToXml(p);
//        System.out.println(s);
//
//        Person p2 = xmlToBean(s,Person.class);
//        System.out.println(p2);

    }
}